ARD2  RC2
Airbag Reference Demonstrator using MPC5604P
SBC_AL.c
Go to the documentation of this file.
00001 
00019 #include "derivative.h"
00020 #include "compile_options.h"
00021 #include "HAL.h"
00022 #include "DSPI.h"
00023 #include "MailScheduler.h"
00024 #include "CG147.h"
00025 #include "CG147_Diag.h"
00026 #include "SBC_AL.h"
00027 #include "Utils.h"
00028 #include "MMA51xx.h"
00029 #include "SIU.h"
00030 /*
00031  ******************************************************************************
00032  * constants
00033  ******************************************************************************
00034  */
00035 /******************************************************************************/
00036 static const uint8_t cau8SBCSquibFiringStatusCmd[] =
00037 {
00038   SBC_FIRE_COUNTER, SBC_FIRE_COUNTER, SBC_FIRE_COUNTER, SBC_FIRE_COUNTER,
00039   SBC_FIRE_COUNTER, SBC_FIRE_COUNTER, SBC_FIRE_COUNTER, SBC_FIRE_COUNTER,
00040   SBC_FIRE_COUNTER, SBC_FIRE_COUNTER, SBC_FIRE_COUNTER, SBC_FIRE_COUNTER,
00041   SBC_FIRE_COUNTER, SBC_CLEAR_FIRE_CNT };
00042 
00043 static const uint8_t cau8SBCSquibFiringStatusArg[] =
00044 {
00045   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x00,
00046   0x00 };
00047 
00049 const uint16_t cu16PresentSquibs = (SQUIB_CH0_PRESENT | /* Driver frontal airbag */
00050     SQUIB_CH1_PRESENT | /* Driver seatbelt pre-tensioner */
00051     SQUIB_CH2_ABSENT | /* Nothing */
00052     SQUIB_CH3_PRESENT | /* Side-passenger frontal airbag */
00053     SQUIB_CH4_PRESENT | /* Side-passenger seat-belt pre-tensioner */
00054     SQUIB_CH5_ABSENT | /* Nothing */
00055     SQUIB_CH6_PRESENT | /* left side-curtain airbag */
00056     SQUIB_CH7_ABSENT | /* Nothing */
00057     SQUIB_CH8_ABSENT | /* Nothing */
00058     SQUIB_CH9_PRESENT | /* right side-curtain airbag */
00059     SQUIB_CH10_ABSENT | /* Nothing */
00060     SQUIB_CH11_ABSENT); /* Nothing */
00062 const uint16_t cu16PresentSatellites = (SAT_CH0_SLOT0_PRESENT | /* Front-left accelerometer */
00063     SAT_CH0_SLOT1_ABSENT | /* Nothing */
00064     SAT_CH0_SLOT2_ABSENT | /* Nothing */
00065     SAT_CH1_SLOT0_PRESENT | /* Front-right accelerometer */
00066     SAT_CH1_SLOT1_ABSENT | /* Nothing */
00067     SAT_CH1_SLOT2_ABSENT | /* Nothing */
00068     SAT_CH2_SLOT0_PRESENT | /* left-side accelerometer */
00069     SAT_CH2_SLOT1_ABSENT | /* Nothing */
00070     SAT_CH2_SLOT2_ABSENT | /* Nothing */
00071     SAT_CH3_SLOT0_PRESENT | /* right-side accelerometer */
00072     SAT_CH3_SLOT1_ABSENT | /* Nothing */
00073     SAT_CH3_SLOT2_ABSENT /* Nothing */
00074 );
00076 const uint16_t cu16FiredSquibs = (SQUIB_CH0_NOT_FIRED | SQUIB_CH0_NOT_FIRED
00077     | SQUIB_CH1_NOT_FIRED | SQUIB_CH2_NOT_FIRED | SQUIB_CH3_NOT_FIRED
00078     | SQUIB_CH4_NOT_FIRED | SQUIB_CH5_NOT_FIRED | SQUIB_CH6_NOT_FIRED
00079     | SQUIB_CH7_NOT_FIRED | SQUIB_CH8_NOT_FIRED | SQUIB_CH9_NOT_FIRED
00080     | SQUIB_CH10_NOT_FIRED | SQUIB_CH11_NOT_FIRED);
00082 const uint16_t cu16CrashedSatellites = (SAT_CH0_SLOT0_NOT_CRASHED
00083     | SAT_CH0_SLOT1_NOT_CRASHED | SAT_CH0_SLOT2_NOT_CRASHED
00084     | SAT_CH1_SLOT0_NOT_CRASHED | SAT_CH1_SLOT1_NOT_CRASHED
00085     | SAT_CH1_SLOT2_NOT_CRASHED | SAT_CH2_SLOT0_NOT_CRASHED
00086     | SAT_CH2_SLOT1_NOT_CRASHED | SAT_CH2_SLOT2_NOT_CRASHED
00087     | SAT_CH3_SLOT0_NOT_CRASHED | SAT_CH3_SLOT1_NOT_CRASHED
00088     | SAT_CH3_SLOT2_NOT_CRASHED);
00090 const uint8_t cu8SBCSatelliteData[] =
00091 {
00092   /* Satellite 1 */
00093   /* PROTOCOL */0x04u,
00094   /* N_DATA_BLOCKS */0x20u,
00095   /* MANUFACTURER */0x46u,
00096   /* SENSOR_TYPE */0x01u,
00097   /* AXIS */0x00u,
00098   /* RANGE */0x09u,
00099   /* DEVCFG2 */0x00u,
00100   /* PRODUCT_REVISION */0x11u,
00101   /* DEVCFG6 */0x00u,
00102   /* PROD_DATE_1 */0x00u,
00103   /* PROD_DATE_2*/0x00u,
00104   /* SN0 */0x00u,
00105   /* SN1 */0x00u,
00106   /* SN2 */0x00u,
00107   /* SN3 */0x00u,
00108   /* INIT_RAW_OFFSET */0x00u,
00109   /* COMBINED_OFFSET_SELF_TEST */0x00u,
00110   /* AVG_SELF_TEST */0x00u,
00111   /* DEVCFG1 */0x00,
00112   /* Satellite 2 */
00113   /* PROTOCOL */0x04u,
00114   /* N_DATA_BLOCKS */0x20u,
00115   /* MANUFACTURER */0x46u,
00116   /* SENSOR_TYPE */0x01u,
00117   /* AXIS */0x00u,
00118   /* RANGE */0x09u,
00119   /* DEVCFG2 */0x00u,
00120   /* PRODUCT_REVISION */0x11u,
00121   /* DEVCFG6 */0x00u,
00122   /* PROD_DATE_1 */0x00u,
00123   /* PROD_DATE_2*/0x00u,
00124   /* SN0 */0x00u,
00125   /* SN1 */0x00u,
00126   /* SN2 */0x00u,
00127   /* SN3 */0x00u,
00128   /* INIT_RAW_OFFSET */0x00u,
00129   /* COMBINED_OFFSET_SELF_TEST */0x00u,
00130   /* AVG_SELF_TEST */0x00u,
00131   /* DEVCFG1 */0x00,
00132   /* Satellite 3 */
00133   /* PROTOCOL */0x04u,
00134   /* N_DATA_BLOCKS */0x20u,
00135   /* MANUFACTURER */0x46u,
00136   /* SENSOR_TYPE */0x01u,
00137   /* AXIS */0x00u,
00138   /* RANGE */0x09u,
00139   /* DEVCFG2 */0x00u,
00140   /* PRODUCT_REVISION */0x11u,
00141   /* DEVCFG6 */0x00u,
00142   /* PROD_DATE_1 */0x00u,
00143   /* PROD_DATE_2*/0x00u,
00144   /* SN0 */0x00u,
00145   /* SN1 */0x00u,
00146   /* SN2 */0x00u,
00147   /* SN3 */0x00u,
00148   /* INIT_RAW_OFFSET */0x00u,
00149   /* COMBINED_OFFSET_SELF_TEST */0x00u,
00150   /* AVG_SELF_TEST */0x00u,
00151   /* DEVCFG1 */0x00,
00152   /* Satellite 4 */
00153   /* PROTOCOL */0x04u,
00154   /* N_DATA_BLOCKS */0x20u,
00155   /* MANUFACTURER */0x46u,
00156   /* SENSOR_TYPE */0x01u,
00157   /* AXIS */0x00u,
00158   /* RANGE */0x09u,
00159   /* DEVCFG2 */0x00u,
00160   /* PRODUCT_REVISION */0x11u,
00161   /* DEVCFG6 */0x00u,
00162   /* PROD_DATE_1 */0x00u,
00163   /* PROD_DATE_2*/0x00u,
00164   /* SN0 */0x00u,
00165   /* SN1 */0x00u,
00166   /* SN2 */0x00u,
00167   /* SN3 */0x00u,
00168   /* INIT_RAW_OFFSET */0x00u,
00169   /* COMBINED_OFFSET_SELF_TEST */0x00u,
00170   /* AVG_SELF_TEST */0x00u,
00171   /* DEVCFG1 */0x00,
00172   /* Satellite 5 */
00173   /* PROTOCOL */0x04u,
00174   /* N_DATA_BLOCKS */0x20u,
00175   /* MANUFACTURER */0x46u,
00176   /* SENSOR_TYPE */0x01u,
00177   /* AXIS */0x00u,
00178   /* RANGE */0x09u,
00179   /* DEVCFG2 */0x00u,
00180   /* PRODUCT_REVISION */0x11u,
00181   /* DEVCFG6 */0x00u,
00182   /* PROD_DATE_1 */0x00u,
00183   /* PROD_DATE_2*/0x00u,
00184   /* SN0 */0x00u,
00185   /* SN1 */0x00u,
00186   /* SN2 */0x00u,
00187   /* SN3 */0x00u,
00188   /* INIT_RAW_OFFSET */0x00u,
00189   /* COMBINED_OFFSET_SELF_TEST */0x00u,
00190   /* AVG_SELF_TEST */0x00u,
00191   /* DEVCFG1 */0x00,
00192   /* Satellite 6 */
00193   /* PROTOCOL */0x04u,
00194   /* N_DATA_BLOCKS */0x20u,
00195   /* MANUFACTURER */0x46u,
00196   /* SENSOR_TYPE */0x01u,
00197   /* AXIS */0x00u,
00198   /* RANGE */0x09u,
00199   /* DEVCFG2 */0x00u,
00200   /* PRODUCT_REVISION */0x11u,
00201   /* DEVCFG6 */0x00u,
00202   /* PROD_DATE_1 */0x00u,
00203   /* PROD_DATE_2*/0x00u,
00204   /* SN0 */0x00u,
00205   /* SN1 */0x00u,
00206   /* SN2 */0x00u,
00207   /* SN3 */0x00u,
00208   /* INIT_RAW_OFFSET */0x00u,
00209   /* COMBINED_OFFSET_SELF_TEST */0x00u,
00210   /* AVG_SELF_TEST */0x00u,
00211   /* DEVCFG1 */0x00,
00212   /* Satellite 7 */
00213   /* PROTOCOL */0x04u,
00214   /* N_DATA_BLOCKS */0x20u,
00215   /* MANUFACTURER */0x46u,
00216   /* SENSOR_TYPE */0x01u,
00217   /* AXIS */0x00u,
00218   /* RANGE */0x09u,
00219   /* DEVCFG2 */0x00u,
00220   /* PRODUCT_REVISION */0x11u,
00221   /* DEVCFG6 */0x00u,
00222   /* PROD_DATE_1 */0x00u,
00223   /* PROD_DATE_2*/0x00u,
00224   /* SN0 */0x00u,
00225   /* SN1 */0x00u,
00226   /* SN2 */0x00u,
00227   /* SN3 */0x00u,
00228   /* INIT_RAW_OFFSET */0x00u,
00229   /* COMBINED_OFFSET_SELF_TEST */0x00u,
00230   /* AVG_SELF_TEST */0x00u,
00231   /* DEVCFG1 */0x00,
00232   /* Satellite 8 */
00233   /* PROTOCOL */0x04u,
00234   /* N_DATA_BLOCKS */0x20u,
00235   /* MANUFACTURER */0x46u,
00236   /* SENSOR_TYPE */0x01u,
00237   /* AXIS */0x00u,
00238   /* RANGE */0x09u,
00239   /* DEVCFG2 */0x00u,
00240   /* PRODUCT_REVISION */0x11u,
00241   /* DEVCFG6 */0x00u,
00242   /* PROD_DATE_1 */0x00u,
00243   /* PROD_DATE_2*/0x00u,
00244   /* SN0 */0x00u,
00245   /* SN1 */0x00u,
00246   /* SN2 */0x00u,
00247   /* SN3 */0x00u,
00248   /* INIT_RAW_OFFSET */0x00u,
00249   /* COMBINED_OFFSET_SELF_TEST */0x00u,
00250   /* AVG_SELF_TEST */0x00u,
00251   /* DEVCFG1 */0x00,
00252   /* Satellite 9 */
00253   /* PROTOCOL */0x04u,
00254   /* N_DATA_BLOCKS */0x20u,
00255   /* MANUFACTURER */0x46u,
00256   /* SENSOR_TYPE */0x01u,
00257   /* AXIS */0x00u,
00258   /* RANGE */0x09u,
00259   /* DEVCFG2 */0x00u,
00260   /* PRODUCT_REVISION */0x11u,
00261   /* DEVCFG6 */0x00u,
00262   /* PROD_DATE_1 */0x00u,
00263   /* PROD_DATE_2*/0x00u,
00264   /* SN0 */0x00u,
00265   /* SN1 */0x00u,
00266   /* SN2 */0x00u,
00267   /* SN3 */0x00u,
00268   /* INIT_RAW_OFFSET */0x00u,
00269   /* COMBINED_OFFSET_SELF_TEST */0x00u,
00270   /* AVG_SELF_TEST */0x00u,
00271   /* DEVCFG1 */0x00,
00272   /* Satellite 10 */
00273   /* PROTOCOL */0x04u,
00274   /* N_DATA_BLOCKS */0x20u,
00275   /* MANUFACTURER */0x46u,
00276   /* SENSOR_TYPE */0x01u,
00277   /* AXIS */0x00u,
00278   /* RANGE */0x09u,
00279   /* DEVCFG2 */0x00u,
00280   /* PRODUCT_REVISION */0x11u,
00281   /* DEVCFG6 */0x00u,
00282   /* PROD_DATE_1 */0x00u,
00283   /* PROD_DATE_2*/0x00u,
00284   /* SN0 */0x00u,
00285   /* SN1 */0x00u,
00286   /* SN2 */0x00u,
00287   /* SN3 */0x00u,
00288   /* INIT_RAW_OFFSET */0x00u,
00289   /* COMBINED_OFFSET_SELF_TEST */0x00u,
00290   /* AVG_SELF_TEST */0x00u,
00291   /* DEVCFG1 */0x00,
00292   /* Satellite 11 */
00293   /* PROTOCOL */0x04u,
00294   /* N_DATA_BLOCKS */0x20u,
00295   /* MANUFACTURER */0x46u,
00296   /* SENSOR_TYPE */0x01u,
00297   /* AXIS */0x00u,
00298   /* RANGE */0x09u,
00299   /* DEVCFG2 */0x00u,
00300   /* PRODUCT_REVISION */0x11u,
00301   /* DEVCFG6 */0x00u,
00302   /* PROD_DATE_1 */0x00u,
00303   /* PROD_DATE_2*/0x00u,
00304   /* SN0 */0x00u,
00305   /* SN1 */0x00u,
00306   /* SN2 */0x00u,
00307   /* SN3 */0x00u,
00308   /* INIT_RAW_OFFSET */0x00u,
00309   /* COMBINED_OFFSET_SELF_TEST */0x00u,
00310   /* AVG_SELF_TEST */0x00u,
00311   /* DEVCFG1 */0x00,
00312   /* Satellite 12 */
00313   /* PROTOCOL */0x04u,
00314   /* N_DATA_BLOCKS */0x20u,
00315   /* MANUFACTURER */0x46u,
00316   /* SENSOR_TYPE */0x01u,
00317   /* AXIS */0x00u,
00318   /* RANGE */0x09u,
00319   /* DEVCFG2 */0x00u,
00320   /* PRODUCT_REVISION */0x11u,
00321   /* DEVCFG6 */0x00u,
00322   /* PROD_DATE_1 */0x00u,
00323   /* PROD_DATE_2*/0x00u,
00324   /* SN0 */0x00u,
00325   /* SN1 */0x00u,
00326   /* SN2 */0x00u,
00327   /* SN3 */0x00u,
00328   /* INIT_RAW_OFFSET */0x00u,
00329   /* COMBINED_OFFSET_SELF_TEST */0x00u,
00330   /* AVG_SELF_TEST */0x00u,
00331   /* DEVCFG1 */0x00 };
00335 const uint8_t cau8SBCSatTestVariableFilter[] =
00336 {
00337   /* PROTOCOL */TRUE,
00338   /* N_DATA_BLOCKS */TRUE,
00339   /* MANUFACTURER */CLEAR,
00340   /* SENSOR_TYPE */TRUE,
00341   /* AXIS */CLEAR,
00342   /* RANGE */CLEAR,
00343   /* DEVCFG2 */CLEAR,
00344   /* PRODUCT_REVISION */CLEAR,
00345   /* DEVCFG6 */CLEAR,
00346   /* PROD_DATE_1 */CLEAR,
00347   /* PROD_DATE_2*/CLEAR,
00348   /* SN0 */CLEAR,
00349   /* SN1 */CLEAR,
00350   /* SN2 */CLEAR,
00351   /* SN3 */CLEAR,
00352   /* INIT_RAW_OFFSET */CLEAR,
00353   /* COMBINED_OFFSET_SELF_TEST */CLEAR,
00354   /* AVG_SELF_TEST */CLEAR,
00355   /* DEVCFG1 */CLEAR, };
00356 /*
00357  ******************************************************************************
00358  * Globals
00359  ******************************************************************************
00360  */
00362 static uint32_t gu32SBCIgnoredResponse;
00364 uint16_t gu16ActivePSI5Channels;
00366 uint16_t gu16ActiveSquibChannels;
00368 uint16_t gu16FiredSquibs;
00370 uint16_t gu16SquibsToFire;
00372 uint16_t gu16CrashedSatellites;
00374 uint16_t gu16ConfirmedSatellites;
00376 uint32_t gu32SBCTime;
00377 uint8_t gu8SBCSatelliteData[SBC_N_SATELLITES_POSSIBLE * MMA5100_N_REGISTERS];
00378 /*
00379  ******************************************************************************
00380  * vfnSBCEnableWarningLamp
00381  * Functional only without any scheduler and 16-bit format
00382  ******************************************************************************
00383  */
00384 uint8_t u8fnSBCPreSchedulerEnableWarningLamp(uint8_t u8Enable)
00385 {
00386   /* Turn lamp warning lamp on or off according to passed arg */
00387   return (u8fnCG147Transcieve(SBC_SET_I_AIO, u8Enable, CG147_SPI_CONFIG));
00388 }
00389 /*
00390  ******************************************************************************
00391  * vfnSBCEnableWarningLamp
00392  * Functional with Scheduled SPI Tx in 17-bit configuration ONLY
00393  ******************************************************************************
00394  */
00395 uint8_t u8fnSBCEnableWarningLamp(uint8_t u8Enable)
00396 {
00397   /* Turn lamp warning lamp on or off according to passed arg */
00398   return (u8fnCG147ScheduleSafeTransfer(CG147_SPI_CONFIG_EXT, 
00399                                         SBC_SET_I_AIO, u8Enable,
00400                                         (uint16_t*)&gu32SBCIgnoredResponse,
00401                                         (uint32_t*)&gu32SBCTime));
00402 }
00403 /*
00404  ******************************************************************************
00405  * vfnSBCPreSchedulerInit
00406  * Functional without a scheduler running only.
00407  ******************************************************************************
00408  */
00409 void vfnSBCPreSchedulerInit(void)
00410 {
00411   vfnCG147Init(CG147_SPI_CONFIG, DSPI0C6, DSPI0C7, PIN_N_SYS_RES);
00412   /* Keep the lamp on */
00413   (void)u8fnSBCPreSchedulerEnableWarningLamp(TRUE);
00414   
00415   return;
00416 }
00417 /*
00418  ******************************************************************************
00419  * u8fnSBCInit
00420  * Requires scheduler to be working, switches between 16- to 17-bit config.
00421  ******************************************************************************
00422  */
00423 uint32_t u32fnSBCInit(void)
00424 {
00425   uint32_t u32Status;
00426   uint16_t u16LocalStatus;
00427   uint32_t u32LocalStatus;
00428   uint32_t au32LocalSchedResults[SBC_N_CONFIG_BUFFER_SIZE];
00429   
00430   /* Init variables */
00431   u16LocalStatus = CLEAR;
00432   u32Status = CLEAR;
00433   u32LocalStatus = CLEAR;
00434   
00435   /* We should load the active PSI5 satellites from NV memory */
00436   gu16ActivePSI5Channels = cu16PresentSatellites;
00437   
00438   /* Also load the active Squib channels */
00439   gu16ActiveSquibChannels = cu16PresentSquibs;
00440   
00441   /* Do the same for fired squibs */
00442   gu16FiredSquibs = cu16FiredSquibs;
00443   
00444   /* And for crashed satellites */
00445   gu16CrashedSatellites = cu16CrashedSatellites;
00446   
00447   if(SBC_N_CONFIG_BUFFER_SIZE >= cu8CG147InitCmdsArgsSize)
00448   {
00449     /* Transfer all this data in 16-bit mode to the device, followed by a */
00450     /* switch to 17-bit mode. */
00451     if(CLEAR == u8fnCG147ScheduleBatchTransfer(CG147_SPI_CONFIG,
00452                                                (uint8_t*)&cau8CG147InitCmdsIn16Bit,
00453                                                (uint8_t*)&cau8CG147InitArgsIn16Bit,
00454                                                (uint16_t*)&au32LocalSchedResults,
00455                                                cu8CG147InitCmdsArgsSize,
00456                                                (uint32_t*)&gu32SBCTime))
00457     { 
00458       /* ******** EVERYTHING AFTER HERE MUST BE IN 17-BIT FORMAT  ****************/
00459       /* Now launch Watch-dog timers with default seeds */
00460       u16LocalStatus = u8fnCG147ScheduleSafeTransfer(CG147_SPI_CONFIG_EXT,
00461                                                      SBC_WD2_TRIGGER,
00462                                                      SBC_WD_RESPONSE_8,
00463                                                      (uint16_t*)&gu32CG147WatchDog2RequestToMCU,
00464                                                      (uint32_t*)&gu32SBCTime);
00465       u16LocalStatus |= u8fnCG147ScheduleSafeTransfer(CG147_SPI_CONFIG_EXT,
00466                                                       SBC_WD3_TRIGGER,
00467                                                       SBC_WD_RESPONSE_8,
00468                                                       (uint16_t*)&gu32CG147WatchDog3RequestToMCU,
00469                                                       (uint32_t*)&gu32SBCTime);
00470       /* Let's continue if life has been good */
00471       if(CLEAR == u16LocalStatus)
00472       {
00473         /* Here we wait for the scheduler to send the above SPI frames */
00474         while(1u > u32fnSchedIsTxDone(gu32SBCTime))
00475         {
00476           /* Wait here */
00477         };
00478 
00479         /* We will now gather initial data for our satellites */
00480         if(MMA5100_SENSOR_READY_STATUS & 
00481             u16fnSBCGatherPSI5SatelliteData((uint8_t*)&gu8SBCSatelliteData))
00482         {
00483           u16LocalStatus = 
00484             u16fnSBCTestPSI5SatelliteData((uint8_t*)&gu8SBCSatelliteData,
00485                                           (uint8_t*)&cu8SBCSatelliteData,
00486                                           (uint8_t*)&cau8SBCSatTestVariableFilter,
00487                                           (uint16_t*)&cu16PresentSatellites);
00488           /* Figure out which are our usable squibs based on this */
00489           gu16ActivePSI5Channels = ((uint16_t)~u16LocalStatus &
00490                                     cu16PresentSatellites);
00491 
00492           /* If the activity above is not transparent, we need to flag it */
00493           if(gu16ActivePSI5Channels == cu16PresentSatellites)
00494           {
00495             /* Nothing */
00496           } /* end if - Present satellites match active satellites */
00497           else 
00498           {
00499             /* Flag in status */
00500             u32Status = (uint32_t)u16LocalStatus;
00501           } /* End else - present satellites do not match active ones */
00502           
00503           /* Run initial tests for the SBC */
00504           u32LocalStatus = u32fnSBCPerformInitialTests();
00505           /* Act according to the status of the performed tests which are defined */
00506           /* within the CG147_Diag.h file.                                        */
00507           u32Status |= (u32LocalStatus << BITS_IN_16);
00508           if(CLEAR == (u32LocalStatus & SBC_DIAG_CRITICAL_FAILURE))
00509           {
00510 #ifdef USE_AUTO_SYNC
00511             /* Switch over to CG147-driven Sync-pulses */
00512             u16LocalStatus = u8fnCG147ScheduleSafeTransfer(CG147_SPI_CONFIG_EXT,
00513                                                            SBC_PROG_PSYNC_MODE, 
00514                                                            (uint8_t)0xC5u,
00515                                                            (uint16_t*)&gu32SBCIgnoredResponse,
00516                                                            (uint32_t*)&gu32SBCTime);
00517 #else
00518             (void)u8fnSBCSchedulePSync();
00519             u16LocalStatus = CLEAR;
00520             
00521 #endif
00522             /* Stop warning lamp and link it to DIS_ALP status */
00523             u16LocalStatus |= u8fnCG147ScheduleSafeTransfer(CG147_SPI_CONFIG_EXT,
00524                                                             SBC_SET_I_AIO, 
00525                                                             (uint8_t)CLEAR,
00526                                                             (uint16_t*)&gu32SBCIgnoredResponse,
00527                                                             (uint32_t*)&gu32SBCTime);
00528             u16LocalStatus |= u8fnCG147ScheduleSafeTransfer(CG147_SPI_CONFIG_EXT,
00529                                                             SBC_PROG_AIO_WL, 
00530                                                             (uint8_t)0x03u,
00531                                                             (uint16_t*)&gu32SBCIgnoredResponse,
00532                                                             (uint32_t*)&gu32SBCTime);
00533             /* Only continue if we're good to go */
00534             /* We have finished all configuration. Schedule EOP */
00535             /* Schedule EOP after config */
00536             u16LocalStatus |= u8fnCG147ScheduleSafeTransfer(CG147_SPI_CONFIG_EXT, 
00537                                                             SBC_EOP, 
00538                                                             (uint8_t)0x03u,
00539                                                             (uint16_t*)&gu32SBCIgnoredResponse,
00540                                                             (uint32_t*)&gu32SBCTime);
00541             /* We're about to leave */
00542             if(CLEAR == u16LocalStatus)
00543             {
00544               /* Done */
00545               DELAY_MSEC(1u);
00546             }
00547             else
00548             {
00549               /* We're bruised */
00550               u32Status |= SBC_TEST_SCHEDULER_FAILED;
00551             }
00552           } /* End if - initial SBC tests were passed */
00553           else
00554           {
00555             u32Status |= SBC_TEST_SBC_FAILED;
00556           }
00557         } /* End if - satellites responded "ready" */
00558         else
00559         {
00560           /* Satellites did not initialize correctly */
00561           u32Status = SBC_TEST_ALL_SAT;
00562         } /* End else - satellites did not respond as "ready" */
00563       } /* End if - Scheduled WD data correctly. */
00564       else
00565       {
00566         /* Problem scheduling data. Exit with error code */
00567         u32Status = SBC_TEST_SCHEDULER_FAILED;
00568       } /* End else - WD scheduled incorrectly */
00569     } /* End if - 16-bit operations occurred successfully */ 
00570     else
00571     {
00572       u32Status = SBC_TEST_UNEXPECTED_SPI_RESULT;
00573     } /* End else: 16-bit operations did not occur successfully */
00574   } /* End if - IntCmds and args is correct */
00575   else
00576   {
00577     /* Programming error - go fix it */
00578     u32Status = 0xFFFFFFFF;
00579   } /* End else - IntCmds and Args is not correct */  
00580   return (u32Status);
00581 }
00582 /*
00583  ******************************************************************************
00584  * u32fnSBCPerformInitialTests
00585  * Functional with Scheduled SPI Tx in 17-bit configuration ONLY
00586  ******************************************************************************
00587  */
00588 uint32_t u32fnSBCPerformInitialTests(void)
00589 {
00590   /* General Status */
00591   uint32_t u32Status;
00592   uint8_t u8Counter;
00593   uint8_t u8TestCounter;
00594   
00595 
00596   u32Status = CLEAR;
00597   
00598   /* Perform POM tests */
00599   for(u8Counter = CLEAR; u8Counter < CG147_N_ER_LINES; u8Counter++)
00600   {
00601     for(u8TestCounter = CLEAR; u8TestCounter < cu8SizeOfSBCTests;
00602         u8TestCounter++)
00603     {
00604       u32Status |= u32fnSBCPerformInitialTestsPOM(u8Counter, u8TestCounter);
00605     }
00606   }
00607   /* At this point, we know whether the SBC is reliable or not as a unit */
00608   if(CLEAR == u32Status)
00609   {
00610     /* Next perform ADC, Mux tests */
00611     for(u8Counter = CLEAR; u8Counter < cu8SizeOfTestAnaHeadSettings; 
00612         u8Counter++)
00613     {
00614       u32Status |= u32fnSBCTestMuxAndADC(u8Counter);
00615     }
00616     
00617     if(((CG147_END_OF_PROGRAMMING_FLAG >> BITS_IN_BYTE) == u32Status) || 
00618        (CLEAR == u32Status)) 
00619     {
00620       /* Continue with FLM tests which will tell us if our squibs are ok */
00621       u32Status = u32fnSBCPerformInitialTestsFLM(gu16ActiveSquibChannels);
00622     }
00623     else
00624     {
00625       u32Status = SBC_TEST_SBC_FAILED;
00626     }
00627   }
00628   else
00629   {
00630     u32Status = SBC_TEST_SBC_FAILED;
00631   }
00632   return (u32Status);
00633 }
00634 /*
00635  ******************************************************************************
00636  * u16fnSBCGatherPSI5SatelliteData
00637  * Functional with Scheduled SPI Tx in 17-bit configuration ONLY
00638  ******************************************************************************
00639  */
00640 uint16_t u16fnSBCGatherPSI5SatelliteData(uint8_t* pu8PSI5Data)
00641 {
00642   /* Local variables */
00643   /* for loop counters */
00644   uint16_t u16Counter1;
00645   uint16_t u16Counter2;
00646   /* Temporary array for 16-bit data */
00647   uint16_t au16SBCSensorSettings[SBC_N_SATELLITES_POSSIBLE
00648   * SBC_SENSOR_DATA_ARRAY_SIZE];
00649   /* Index memory per data-nibble received */
00650   uint8_t au8SatIndex[SBC_N_SATELLITES_POSSIBLE];
00651   uint8_t au8SatIndexAdder[SBC_N_SATELLITES_POSSIBLE];
00652   uint32_t au32SatAlreadyWrittenMem[SBC_N_SATELLITES_POSSIBLE];
00653   /* Array to receive acceleration data */
00654   uint32_t au32TempRawDataDepot[5u];
00655   /* Mask used in inner for loop */
00656   uint16_t u16Mask;
00657   /* Status register */
00658   uint16_t u16Status;
00659 
00660   /* Init locals */
00661   u16Mask = CG147_SAT_MASK_MIN;
00662   u16Status = CLEAR;
00663   for(u16Counter1 = CLEAR; u16Counter1 < N_ELEMENTS(au32TempRawDataDepot); u16Counter1++)
00664   {
00665     au32TempRawDataDepot[u16Counter1] = CLEAR;
00666   }
00667   for(u16Counter1 = CLEAR; u16Counter1 < N_ELEMENTS(au16SBCSensorSettings); u16Counter1++)
00668   {
00669     au16SBCSensorSettings[u16Counter1] = CLEAR;
00670   }
00671   for(u16Counter1 = CLEAR; u16Counter1 < SBC_N_SATELLITES_POSSIBLE; u16Counter1++)
00672   {
00673     au8SatIndex[u16Counter1] = CLEAR;
00674     au8SatIndexAdder[u16Counter1] = CLEAR;
00675     au32SatAlreadyWrittenMem[u16Counter1] = CLEAR;
00676   }
00677 
00678   /* Wait for satellites to wake-up */
00679   DELAY_MSEC(195u);
00680 
00681   /* We will now gather and treat all data */
00682   for(u16Counter1 = CLEAR; u16Counter1 < N_ELEMENTS(au16SBCSensorSettings);
00683       u16Counter1 += SBC_N_SATELLITES_POSSIBLE)
00684   {
00685     /* Generate PSI5 sync pulse */
00686     vfnCG147SyncPulse(PIN_N_SYNC);
00687     SCHED_WHAT_IS_THE_TIME(gu32SBCTime);
00688     while (SCHED_500US_PERIOD > u32fnSchedHasTimeElapsed(gu32SBCTime))
00689     {
00690       /* Wait for two clicks to pass */
00691     }
00692 
00693     /* First, we need to gather data from satellites */
00694     (void)u32fnSBCSchedulePSISat((uint16_t*)&au32TempRawDataDepot);
00695 
00696     /* Reset mask for operations coming up */
00697     u16Mask = CG147_SAT_MASK_MIN;
00698 
00699     while (1u > u32fnSchedIsTxDone(gu32SBCTime))
00700     {
00701       /* Wait for one click to pass */
00702 
00703     }
00704 
00705     /* We have started getting data. Decode whatever we got in 32-bit to 16-bit format. */
00706     (void)u16fnCG147ExtractScheduledPSI5Accel((uint32_t*)&au32TempRawDataDepot,
00707     (uint16_t*)&(au16SBCSensorSettings[u16Counter1]),
00708     gu16ActivePSI5Channels);
00709 
00710     /* Next, we will figure out what this data means */
00711     for(u16Counter2 = CLEAR; u16Counter2 < SBC_N_SATELLITES_POSSIBLE; u16Counter2++)
00712     {
00713       /* Only if the satellite channel is active */
00714       if(gu16ActivePSI5Channels & u16Mask)
00715       {
00716         u16Status |= u16fnMMA5100TreatData((uint16_t*)&(au16SBCSensorSettings[u16Counter1 + u16Counter2]),
00717                                            (uint8_t*)&(pu8PSI5Data[(u16Counter2 * MMA5100_N_REGISTERS)]),
00718                                            (uint8_t*)&(au8SatIndex[u16Counter2]),
00719                                            (uint8_t*)&(au8SatIndexAdder[u16Counter2]),
00720                                            (uint32_t*)&(au32SatAlreadyWrittenMem[u16Counter2]));
00721       }
00722       else
00723       {
00724         /* Inactive sensor channel */
00725       }
00726       u16Mask <<= BIT0;
00727     }
00728     
00729   }
00730   return(u16Status);
00731 }
00732 /*
00733  ******************************************************************************
00734  * u16fnSBCTestPSI5SatelliteData
00735  * Functional with Scheduled SPI Tx in 17-bit configuration ONLY
00736  ******************************************************************************
00737  */
00738 static uint16_t u16fnSBCTestPSI5SatelliteData(const uint8_t* au8SBCSatData,
00739                                               const uint8_t* au8SBCSatBasis,
00740                                               const uint8_t* au8SBCSatTestFilt,
00741                                               const uint16_t* pu16ActiveSat)
00742 {
00743   uint16_t u16Status;
00744   uint16_t u16Mask;
00745   uint8_t u8Counter1;
00746   uint8_t u8Counter2;
00747   uint16_t u16LocalIndex;
00748 
00749   u16Status = CLEAR;
00750 
00751   u16Mask = CG147_SAT_MASK_MIN;
00752 
00753   for(u8Counter1 = CLEAR; u8Counter1 < SBC_N_SATELLITES_POSSIBLE; u8Counter1++)
00754   {
00755     if(u16Mask & *pu16ActiveSat)
00756     {
00757       for(u8Counter2 = CLEAR; u8Counter2 < MMA5100_N_REGISTERS; u8Counter2++)
00758       {
00759         if(TRUE == au8SBCSatTestFilt[u8Counter2])
00760         {
00761           u16LocalIndex = ((uint16_t)(MMA5100_N_REGISTERS * u8Counter1) +
00762           (uint16_t)u8Counter2);
00763           if(au8SBCSatData[u16LocalIndex] == au8SBCSatBasis[u16LocalIndex])
00764           {
00765             /* This is good - we passed the test */
00766           }
00767           else
00768           {
00769             /* This is bad - we failed the test and must report it */
00770             u16Status |= (BIT0 << u8Counter1);
00771           }
00772         }
00773         else
00774         {
00775           /* No test to perform */
00776         }
00777       }
00778     }
00779     else
00780     {
00781       /* Skip */
00782     }
00783     u16Mask <<= BIT0;
00784   }
00785 
00786   return (u16Status);
00787 }
00788 /*
00789  ******************************************************************************
00790  * u32fnSBCSchedulePSISat
00791  * Functional with Scheduled SPI Tx in 17-bit configuration ONLY
00792  ******************************************************************************
00793  */
00794 uint32_t u32fnSBCSchedulePSISat(uint16_t* pu16RawAccelArray)
00795 {
00796   uint32_t u32Status;
00797 
00798   u32Status = u8fnCG147ScheduleSafePSI5Accel(CG147_SPI_CONFIG_EXT_MONITORING,
00799                                               gu16ActivePSI5Channels,
00800                                               (uint32_t*)pu16RawAccelArray,
00801                                               (uint32_t*)&gu32SBCTime);
00802   
00803   if(u32Status != CLEAR)
00804   {
00805     u32Status = STATUS_SCHEDULER_PROBLEM;
00806   }
00807   else
00808   {
00809     /* Nothing to do */
00810   }
00811   return (u32Status);
00812 }
00813 /*
00814  ******************************************************************************
00815  * u8fnSBCSchedulePSync
00816  * Functional with Scheduled SPI Tx in 17-bit configuration ONLY
00817  ******************************************************************************
00818  */
00819 uint8_t u8fnSBCSchedulePSync(void)
00820 {
00821   return(u8fnCG147ScheduleSafeTransfer(CG147_SPI_CONFIG_EXT,
00822                                        SBC_PSI_SYNC_GEN, 
00823                                        CLEAR,
00824                                        (uint16_t*)&gu32SBCIgnoredResponse,
00825                                        (uint32_t*)&gu32SBCTime));
00826 }
00827 /*
00828  ******************************************************************************
00829  * u8fnSBCSyncSM
00830  * Functional with Scheduler
00831  ******************************************************************************
00832  */
00833 uint8_t u8fnSBCSyncSM(const uint8_t cu8Period)
00834 {
00835   uint8_t u8Status;
00836   
00837   u8Status = CLEAR;
00838   
00839   while(cu8Period != gu16CG147WatchDog2IsrCount)
00840   {
00841     /* Wait */
00842   }
00843   
00844   return(u8Status);
00845 }
00846 /*
00847  ******************************************************************************
00848  * u32fnSBCExtractPSISat
00849  * Functional with Scheduled SPI Tx in 17-bit configuration ONLY
00850  ******************************************************************************
00851  */
00852 uint32_t u32fnSBCExtractPSISat(uint16_t* pu16RawAccelArray,
00853                                uint16_t* pu16Filtered)
00854 {
00855   uint32_t u32Status;
00856   uint8_t u8Index;
00857 
00858   u32Status = u16fnCG147ExtractScheduledPSI5Accel((uint32_t*)pu16RawAccelArray,
00859   pu16Filtered,
00860   gu16ActivePSI5Channels);
00861   /* Filter signed data to unsigned centered at 512 cts */
00862   for(u8Index = CLEAR; u8Index < SBC_N_SATELLITES_POSSIBLE; u8Index++)
00863   {
00864     if((*pu16Filtered >= MMA5100_UL_FOR_DATA)
00865     || (*pu16Filtered <= MMA5100_LL_FOR_STATUS))
00866     {
00867       /* We are happy */
00868       *pu16Filtered = u16fn10BitOffsetFilter(*pu16Filtered);
00869     }
00870     else
00871     {
00872       u32Status |= ((gu16ActivePSI5Channels) & (BIT0 << u8Index));
00873       *pu16Filtered = 0x021Fu;
00874     }
00875 
00876     pu16Filtered++;
00877   }
00878 
00879   return (u32Status);
00880 }
00881 /*
00882  ******************************************************************************
00883  * u32fnSBCScheduleCmd
00884  * Functional with Scheduled SPI Tx in 17-bit configuration ONLY
00885  ******************************************************************************
00886  */
00887 uint32_t u32fnSBCScheduleCmd(uint8_t u8Cmd, uint8_t u8Arg,
00888                              uint16_t* pu16Response)
00889 {
00890   uint32_t u32Status;
00891   u32Status = u8fnCG147ScheduleSafeTransfer( CG147_SPI_CONFIG_EXT, u8Cmd, u8Arg,
00892                                              pu16Response,
00893                                              (uint32_t*)&gu32SBCTime);
00894   if(CLEAR == u32Status)
00895   {
00896     /* leave */
00897   }
00898   else
00899   {
00900     /* Flag it as a problem */
00901     u32Status = STATUS_SCHEDULER_PROBLEM;
00902   }
00903 
00904   return (u32Status);
00905 }
00906 /*
00907  ******************************************************************************
00908  * u32fnSBCFireSquibs
00909  * Functional with Scheduled SPI Tx in 17-bit configuration ONLY
00910  ******************************************************************************
00911  */
00912 uint32_t u32fnSBCFireSquibs(const uint16_t cu16SquibMask)
00913 {
00914   uint32_t u32Status;
00915 
00916   /* There's no case in executing this fn if the mask is empty */
00917   if(CLEAR != cu16SquibMask)
00918   {
00919     u32Status = u8fnCG147ScheduleSafeSquibFireStart(CG147_SPI_CONFIG_EXT,
00920                                                     cu16SquibMask,
00921                                                     (uint32_t*)&gu32SBCTime);
00922     if(CLEAR != u32Status)
00923     {
00924       u32Status = STATUS_SCHEDULER_PROBLEM;
00925     }
00926     else
00927     {
00928       /* Continue */
00929 
00930       /* Wait for Squibs to fire */
00931       DELAY_MSEC(2u);
00932 
00933       /* Stop firing squibs */
00934       u32Status = u8fnCG147ScheduleSafeSquibFireStop(CG147_SPI_CONFIG_EXT,
00935                                                      (uint32_t*)&gu32SBCTime);
00936       if(CLEAR != u32Status)
00937       {
00938         u32Status = STATUS_SCHEDULER_PROBLEM;
00939       }
00940       else
00941       {
00942         /* Nothing */
00943       }
00944     }
00945   }
00946   else
00947   {
00948     /* Get out */
00949     u32Status = CLEAR;
00950   }
00951 
00952   return (u32Status);
00953 }
00954 /*
00955  ******************************************************************************
00956  * u32fnSBCSquibFiringStatus
00957  * Functional with Scheduled SPI Tx in 17-bit configuration ONLY
00958  ******************************************************************************
00959  */
00960 uint32_t u32fnSBCSquibFiringStatus(uint16_t* pu16Response)
00961 {
00962   uint32_t u32Status;
00963   uint8_t u8LocalStatus;
00964   uint8_t u8Index;
00965   uint32_t au32LocalResults[N_ELEMENTS(cau8SBCSquibFiringStatusCmd)];
00966   uint8_t au8LocalResults[N_ELEMENTS(cau8SBCSquibFiringStatusCmd)];
00967 
00968   u32Status = u8fnCG147ScheduleSafeBatchTransfer(CG147_SPI_CONFIG_EXT,
00969                                                  (uint8_t*)cau8SBCSquibFiringStatusCmd,
00970                                                  (uint8_t*)cau8SBCSquibFiringStatusArg,
00971                                                  (uint16_t*)au32LocalResults,
00972                                                  N_ELEMENTS(cau8SBCSquibFiringStatusCmd),
00973                                                  (uint32_t*)&gu32SBCTime);
00974   
00975   /* Init some variables while we wait for the transfer to occur */
00976   *pu16Response = CLEAR;
00977   u8LocalStatus = CLEAR;
00978   u8Index = CLEAR;
00979   
00980   /* Continue only if the transfer was scheduled correctly */
00981   if(u32Status == CLEAR)
00982   {
00983     while(1u > u32fnSchedIsTxDone(gu32SBCTime))
00984     {
00985       /* Wait here for the transfer to happen */
00986     };
00987 
00988     /* We will ignore the first response since, according to the CG147's */
00989     /* spec, it contains unknown data.                                   */
00990     for(; u8Index < (N_ELEMENTS(cau8SBCSquibFiringStatusCmd) - 1u);
00991         u8Index++)
00992     {
00993       u8LocalStatus = u8fnCG147ExtractResponse((uint32_t*)&au32LocalResults[u8Index + 1u],
00994                                                (uint8_t*)&au8LocalResults[u8Index]);
00995 
00996       if(CLEAR == u8LocalStatus)
00997       {
00998         if(au8LocalResults[u8Index] > SBC_FIRED_SQUIB_MIN_TIME)
00999         {
01000           *pu16Response |= (BIT0 << (u8Index));
01001         }
01002         else
01003         {
01004           /* Nothing */
01005         } /* end else Min time surpassed */
01006       } /* End if u32TempStatus is clear */
01007       else
01008       {
01009         /* Failed. Leave */
01010         u32Status = STATUS_DATA_TRANSFER_ERROR;
01011         break;
01012       } /* End else u32TempStatus is (not) clear */
01013     }
01014     /* End FOR */
01015   }
01016   else
01017   {
01018     /* Exit */
01019     u32Status = STATUS_SCHEDULER_PROBLEM;
01020   }
01021   return (u32Status);
01022 }
01023 /*
01024  ******************************************************************************
01025  *
01026  *  End of file.
01027  *
01028  ******************************************************************************
01029  */